package me.minecraft.mod.resourcepackdemo;

import java.io.*;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @author langle__
 * @version 1.0
 */
public class Main {

    public static void main(String[] args) {
        File inputFile = new File("input");
        File outputFile = new File("output");
        if (!inputFile.exists() && !inputFile.mkdirs()) {
            System.out.println("Failed to create input directory");
            return;
        }
        if (!outputFile.exists() && !outputFile.mkdirs()) {
            System.out.println("Failed to create output directory");
            return;
        }

        System.out.println("清理输出目录中的旧ZIP文件...");
        File[] tempFileList = outputFile.listFiles(f -> f.getName().endsWith(".zip"));
        if (tempFileList != null) {
            for (File file : tempFileList) {
                if (file.delete()) {
                    System.out.println("Deleted " + file.getName());
                }
            }
        }

        System.out.println("扫描输入目录中的ZIP文件...");
        File[] files = inputFile.listFiles(f -> f.getName().endsWith(".zip"));
        if (files == null) {
            System.out.println("No files found in input directory");
            return;
        }

        System.out.println("找到 " + files.length + " 个ZIP文件待处理");

        for (File file : files) {
            System.out.println("正在处理文件: " + file.getName());
            try (
                    ZipFile zipFile = new ZipFile(file);
                    ZipOutputStream output = new ZipOutputStream(Files.newOutputStream(new File(outputFile, file.getName()).toPath()))
            ) {
                Enumeration<? extends ZipEntry> entries = zipFile.entries();
                int entryCount = 0;
                while (entries.hasMoreElements()) {
                    ZipEntry entry = entries.nextElement();
                    if (entry.isDirectory() && entry.getSize() == 0) continue;
                    String entryName = entry.getName();
                    entryCount++;

                    boolean flag = false;
                    if (shouldPreserveEntry(entryName)) {
                        System.out.println("  保留特殊文件: " + entryName);
                        output.putNextEntry(new ZipEntry(entryName));
                    } else if (entry.isDirectory()) {
                        output.putNextEntry(new ZipEntry(entryName));
                    } else {
                        System.out.println("  处理并转置字节: " + entryName);
                        output.putNextEntry(new ZipEntry(entryName + "\\"));
                        flag = true;
                    }
                    try (InputStream inputStream = zipFile.getInputStream(entry)) {
                        InputStream input = flag ? swapBytes(inputStream) : inputStream;
                        byte[] buffer = new byte[8196];
                        int length;
                        while ((length = input.read(buffer)) > 0) {
                            output.write(buffer, 0, length);
                        }
                    }
                    output.closeEntry();
                }
                System.out.println("  完成处理 " + file.getName() + "，共处理 " + entryCount + " 个条目");
            } catch (IOException e) {
                System.err.println("处理文件 " + file.getName() + " 时出错: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
        System.out.println("所有文件处理完成");
    }

    public static InputStream swapBytes(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[8196];
        int read;
        while ((read = input.read(buffer)) != -1) {
            output.write(buffer, 0, read);
        }
        byte[] byteArray = output.toByteArray();
        byte[] tempArray = new byte[byteArray.length];
        for (int i = 0; i < byteArray.length - 1; i += 2) {
            tempArray[i] = byteArray[i + 1];
            tempArray[i + 1] = byteArray[i];
        }
        if (byteArray.length % 2 != 0) {
            tempArray[byteArray.length - 1] = byteArray[byteArray.length - 1];
        }
        return new ByteArrayInputStream(tempArray);
    }

    public static boolean shouldPreserveEntry(String entryName) {
        return entryName.equalsIgnoreCase("pack.mcmeta") ||
                entryName.equalsIgnoreCase("pack.png") ||
                entryName.matches("^.*lang.*\\.json$");
    }

}
